package com.maserb.monitor.dataCenter.communication;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

public class MonitorMessageDecoder extends ByteToMessageDecoder {
    /**
     * HEAD_DATA+CONTENT_LENGTH+CONTENT_TYPE
     */
    public final int PACKAGE_LENGTH = 4 + 4 + 4;

    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
                          List<Object> out) throws Exception {
        // 记录包头开始的index
        int beginReader;

        while (true) {
            // 获取包头开始的index
            beginReader = buffer.readerIndex();
            // 标记包头开始的index
            buffer.markReaderIndex();
            byte[] headData = new byte[4];
            buffer.readBytes(headData);
            int head = ReceiveConverter.convertInt(headData);
            // 读到了协议的开始标志，结束while循环
            if (head == MonitorMessageProtocol.HEAD_DATA) {
                break;
            }

            // 未读到包头，略过一个字节
            // 每次略过，一个字节，去读取，包头信息的开始标记
            buffer.resetReaderIndex();
            buffer.readByte();
        }

        // 当略过，一个字节之后，
        // 数据包的长度，又变得不满足
        // 此时，应该结束。等待后面的数据到达
        if (buffer.readableBytes() < PACKAGE_LENGTH) {
            buffer.readerIndex(beginReader);
            return;
        }

        byte[] contentTypeData = new byte[4];
        buffer.readBytes(contentTypeData);
        int contentType = ReceiveConverter.convertInt(contentTypeData);
        // 判断请求数据包数据是否到齐
        if (buffer.readableBytes() < contentType) {
            buffer.readerIndex(beginReader);
            return;
        }

        // 消息的长度
        byte[] contentLengthData = new byte[4];
        buffer.readBytes(contentLengthData);
        int contentLength = ReceiveConverter.convertInt(contentLengthData);
        // 判断请求数据包数据是否到齐
        if (buffer.readableBytes() < contentLength) {
            buffer.readerIndex(beginReader);
            return;
        }

        byte[] data = new byte[buffer.readableBytes()];
        buffer.readBytes(data);

        MonitorMessageProtocol protocol = new MonitorMessageProtocol(data.length, contentType, data);
        out.add(protocol);
    }
}
